package patterns;

import java.util.ArrayList;
import java.util.List;

public class LearnDecorator {
    public static void main(String[] args) {
        // 装饰者模式允许你在不修改原类的前提下，动态为对象添加功能，通过“层层包装”的方式实现功能增强。
        // 其实比较像静态代理，都是一个新的类中有一个旧的类的对象，在这个旧对象基础上新增功能。
        // 但是区别是装饰的目的是增强，而代理的目的是控制。
        // 例子：一个角色身上有各种装备
        Character character = new Character();
        IEquipment arm = new BlueStone(new RedStone(new ArmEquipment()));
        IEquipment shoe = new BlueStone(new ShoeEquipment());
        character.addEquipment(arm);
        character.addEquipment(shoe);
        character.printAllDescription();
        System.out.println("攻击力：" + character.getAttack());
        System.out.println("防御力：" + character.getDefence());
    }
}

// 角色
class Character {
    List<IEquipment> equipmentList;
    public Character() {
        equipmentList = new ArrayList<>();
    }

    public void addEquipment(IEquipment equipment) {
        equipmentList.add(equipment);
    }

    public void printAllDescription() {
        for (IEquipment equipment : equipmentList) {
            System.out.println(equipment.description());
        }
    }

    public int getAttack() {
        int attack = 0;
        for (IEquipment equipment : equipmentList) {
            attack += equipment.calculateAttack();
        }
        return attack;
    }

    public int getDefence() {
        int defence = 0;
        for (IEquipment equipment : equipmentList) {
            defence += equipment.calculateDefence();
        }
        return defence;
    }
}

// 装备接口
interface IEquipment {
    int calculateAttack();
    int calculateDefence();
    String description();
}

// 一个武器
class ArmEquipment implements IEquipment {

    @Override
    public int calculateAttack() {
        return 20;
    }

    @Override
    public int calculateDefence() {
        return 10;
    }

    @Override
    public String description() {
        return "无尽之刃";
    }
}

// 一个鞋子
class ShoeEquipment implements IEquipment {

    @Override
    public int calculateAttack() {
        return 10;
    }

    @Override
    public int calculateDefence() {
        return 5;
    }

    @Override
    public String description() {
        return "三速鞋";
    }
}

// 装备上的宝石接口
interface IStone extends IEquipment {

}

// 红宝石
class RedStone implements IStone {
    private IEquipment equipment;

    public RedStone (IEquipment equipment) {
        this.equipment = equipment;
    }

    @Override
    public int calculateAttack() {
        return equipment.calculateAttack() + 10;
    }

    @Override
    public int calculateDefence() {
        return equipment.calculateDefence();
    }

    @Override
    public String description() {
        return equipment.description() + " + 红宝石";
    }
}

// 蓝宝石
class BlueStone implements IStone {
    private IEquipment equipment;

    public BlueStone (IEquipment equipment) {
        this.equipment = equipment;
    }

    @Override
    public int calculateAttack() {
        return equipment.calculateAttack();
    }

    @Override
    public int calculateDefence() {
        return equipment.calculateDefence() + 10;
    }

    @Override
    public String description() {
        return equipment.description() + " + 蓝宝石";
    }
}
